package com.huawei.aiosproj.view;

import android.Manifest;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.huawei.aiosproj.R;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.provider.Telephony;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.provider.CalendarContract;

import com.huawei.aiosproj.guiagent.GUIAgentService;

public class CardActivity extends AppCompatActivity {
    private RecyclerView recyclerView;
    private CardAdapter adapter;

    private List<CardItem> cardItems;
    private static final String TAG = "CardActivity";
    private static final int PERMISSION_REQUEST_CODE = 0;
    private static final int ACCESSIBILITY_REQUEST_CODE = 1;

    private static final int PERMISSION_REQUEST_CODE_CALL_SMS = 103;
    private static final int CALL_PERMISSION_CODE = 101;
    private static final int READ_SMS_PERMISSION_CODE = 104;
    private static final int CALENDAR_PERMISSION_CODE = 102;
    private static final int PERMISSION_REQUEST_CODE_CALL_SMS_STATE_CALENDAR = 104;

    private Button btnCall;
    private Button btnStartGuiAgent;
    private ProgressBar loadingIndicator;
    private final String JSON_FILE_NAME = "data.json";
    private final String MODELS_DIR_NAME = "models";
    private final int FILE_CHECK_INTERVAL_MS = 1000;

    private Handler fileCheckHandler;
    private ExecutorService executorService;

    private TelephonyManager telephonyManager;
    private PhoneStateListener phoneStateListener;
    private boolean isCallActive = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(
                WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN
        );
        setContentView(R.layout.activity_card);

        btnCall = findViewById(R.id.buttonBottom);
        btnStartGuiAgent = findViewById(R.id.guiAgentAction);
        loadingIndicator = findViewById(R.id.loadingIndicator);
        btnStartGuiAgent.setEnabled(false);
        btnStartGuiAgent.setAlpha(0.5f);
        btnCall.setOnClickListener(v -> {
            if (checkCallAndSmsPermissions()) {
                makePhoneCallAndPrepareToReadSms();
            }
        });

        btnStartGuiAgent.setOnClickListener(v -> requestAccessibilityPermission());

        getWindow().setStatusBarColor(Color.TRANSPARENT);
        getWindow().getDecorView().setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

        recyclerView = findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        cardItems = new ArrayList<>();
        adapter = new CardAdapter(cardItems, this);
        recyclerView.setAdapter(adapter);

        int cardHeightDp = 300;
        int peekHeightDp = 88;
        int topCardMarginDp = 8;

        StackedCardItemDecoration itemDecoration = new StackedCardItemDecoration(
                this,
                cardHeightDp,
                peekHeightDp,
                topCardMarginDp
        );
        recyclerView.addItemDecoration(itemDecoration);
        ItemTouchHelper.Callback callback = new DragAndDropCallback(adapter, cardItems);
        ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
        touchHelper.attachToRecyclerView(recyclerView);
        executorService = Executors.newSingleThreadExecutor();
        fileCheckHandler = new Handler(Looper.getMainLooper());
        startFileCheckingLoop();
        setupPhoneStateListener();
    }

    private boolean checkCallAndSmsPermissions() {
        List<String> permissionsToRequest = new ArrayList<>();
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
            permissionsToRequest.add(Manifest.permission.CALL_PHONE);
        }
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) {
            permissionsToRequest.add(Manifest.permission.READ_SMS);
        }
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            permissionsToRequest.add(Manifest.permission.READ_PHONE_STATE);
        }
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
            permissionsToRequest.add(Manifest.permission.WRITE_CALENDAR);
        }
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
            permissionsToRequest.add(Manifest.permission.READ_CALENDAR);
        }

        if (!permissionsToRequest.isEmpty()) {
            ActivityCompat.requestPermissions(this, permissionsToRequest.toArray(new String[0]), PERMISSION_REQUEST_CODE_CALL_SMS_STATE_CALENDAR);
            return false;
        }

        return true;
    }

    private void makePhoneCallAndPrepareToReadSms() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED ||
                ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(this, "部分权限未授予：日历功能将不可用。", Toast.LENGTH_LONG).show();
        }
        LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
        if (layoutManager == null) {
            Toast.makeText(this, "无法获取布局管理器", Toast.LENGTH_SHORT).show();
            return;
        }

        if (adapter != null && adapter.getItemCount() > 0) {
            CardItem topCardItem = adapter.getItem(0); // Assuming top card is at position 0
            if (topCardItem != null && topCardItem.getPhone() != null && !topCardItem.getPhone().isEmpty() && !topCardItem.getPhone().equals("N/A")) {
                String phoneNumber = topCardItem.getPhone();
                try {
                    Intent callIntent = new Intent(Intent.ACTION_CALL);
                    callIntent.setData(Uri.parse("tel:" + phoneNumber));
//                    callIntent.setData(Uri.parse("tel:" + "10086"));
                    startActivity(callIntent);
                    isCallActive = true;
                    Toast.makeText(this, "拨打电话中... 电话结束后将尝试读取短信。", Toast.LENGTH_LONG).show();

                } catch (SecurityException e) {
                    Log.e(TAG, "拨打电话权限被拒绝或号码无效", e);
                    Toast.makeText(this, "无法拨打电话: 权限被拒绝或号码无效", Toast.LENGTH_SHORT).show();
                    isCallActive = false;
                }
            } else {
                Toast.makeText(this, "当前卡片没有有效的电话号码", Toast.LENGTH_SHORT).show();
            }
        } else {
            Toast.makeText(this, "没有卡片数据可供拨打", Toast.LENGTH_SHORT).show();
        }
    }

    private void setupPhoneStateListener() {
        telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        phoneStateListener = new PhoneStateListener() {
            private int lastState = TelephonyManager.CALL_STATE_IDLE;

            @Override
            public void onCallStateChanged(int state, String phoneNumber) {
                super.onCallStateChanged(state, phoneNumber);
                switch (state) {
                    case TelephonyManager.CALL_STATE_IDLE:
                        if (lastState == TelephonyManager.CALL_STATE_OFFHOOK && isCallActive) {
                            Log.e(TAG, "电话已挂断或结束。");
                            Toast.makeText(CardActivity.this, "电话已结束。", Toast.LENGTH_SHORT).show();
                            isCallActive = false;
                            enableGuiAgentButton(true); // 电话结束后启用 GUI Agent 按钮
                            new Handler(Looper.getMainLooper()).postDelayed(() -> {
                                Log.d(TAG, "尝试读取最新短信...");
                                readLatestSms();
                            }, 2000);
                        }
                        break;
                    case TelephonyManager.CALL_STATE_OFFHOOK:
                        Log.e(TAG, "电话接通中 (Off-hook)。");
                        isCallActive = true;
                        break;
                    case TelephonyManager.CALL_STATE_RINGING:
                        Log.e(TAG, "电话呼入中 (Ringing)。");
                        break;
                }
                lastState = state;
            }
        };

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)
                == PackageManager.PERMISSION_GRANTED) {
            telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
        } else {
            Log.w(TAG, "READ_PHONE_STATE permission not granted. Cannot listen for call state changes.");
        }
    }

    private void readLatestSms() {
        Log.e(TAG, "readLatestSms: " + "开始读取短信");
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS)
                != PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(this, "读取短信权限未授予", Toast.LENGTH_SHORT).show();
            return;
        }

        ContentResolver contentResolver = getContentResolver();
        Uri smsUri = Telephony.Sms.Inbox.CONTENT_URI;
        Cursor cursor = contentResolver.query(smsUri,
                new String[]{Telephony.Sms.Inbox.BODY, Telephony.Sms.Inbox.ADDRESS, Telephony.Sms.Inbox.DATE},
                null,
                null,
                Telephony.Sms.Inbox.DEFAULT_SORT_ORDER + " LIMIT 1");

        if (cursor != null) {
            try {
                if (cursor.moveToFirst()) {
                    String body = cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Sms.Inbox.BODY));
                    if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR) == PackageManager.PERMISSION_GRANTED &&
                            ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_GRANTED) {
                        parseSmsAndCreateCalendarEvent(body);
                    } else {
                        Toast.makeText(this, "日历权限未授予，无法创建事件", Toast.LENGTH_LONG).show();
                    }
                    String address = cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Sms.Inbox.ADDRESS));
                    long dateMillis = cursor.getLong(cursor.getColumnIndexOrThrow(Telephony.Sms.Inbox.DATE));
                    Date date = new Date(dateMillis);
                    String smsDetails = "最新短信来自: " + address + "\n内容: " + body.substring(0, Math.min(body.length(), 50)) + "...\n时间: " + date.toString(); // Truncate for toast
                    Log.e(TAG, "readLatestSms: " + smsDetails);
                } else {
                    Log.d(TAG, "收件箱中没有短信。");
                    Toast.makeText(this, "收件箱中没有短信。", Toast.LENGTH_SHORT).show();
                }
            } catch (IllegalArgumentException e) {
                Log.e(TAG, "Error accessing SMS column: " + e.getMessage());
                Toast.makeText(this, "读取短信时发生错误。", Toast.LENGTH_SHORT).show();
            } finally {
                cursor.close();
            }
        } else {
            Log.e(TAG, "查询短信时光标为空。");
            Toast.makeText(this, "无法查询短信。", Toast.LENGTH_SHORT).show();
        }
    }

    private void enableGuiAgentButton(boolean enable) {
        btnStartGuiAgent.setEnabled(enable);
        btnStartGuiAgent.setAlpha(enable ? 1.0f : 0.5f);
    }

    private void requestAccessibilityPermission() {
        if (!isAccessibilityServiceEnabled(this, GUIAgentService.class)) {
            Toast.makeText(this, "请授予无障碍权限以启动 GUI Agent", Toast.LENGTH_LONG).show();
            Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
            startActivityForResult(intent, ACCESSIBILITY_REQUEST_CODE);
        } else {
            startGuiAgentService();
        }
    }

    public static boolean isAccessibilityServiceEnabled(Context context, Class<?> accessibilityServiceClass) {
        ComponentName expectedComponentName = new ComponentName(context, accessibilityServiceClass);
        String enabledServicesSetting = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
        if (enabledServicesSetting == null) {
            return false;
        }
        TextUtils.SimpleStringSplitter colonSplitter = new TextUtils.SimpleStringSplitter(':');
        colonSplitter.setString(enabledServicesSetting);
        while (colonSplitter.hasNext()) {
            String componentNameString = colonSplitter.next();
            ComponentName enabledService = ComponentName.unflattenFromString(componentNameString);
            if (enabledService != null && enabledService.equals(expectedComponentName)) {
                return true;
            }
        }
        return false;
    }

    private void startGuiAgentService() {
        if (isAccessibilityServiceEnabled(this, GUIAgentService.class)) {
            Intent intent = new Intent(this, GUIAgentService.class);
            startService(intent);
            Toast.makeText(this, "GUI Agent 服务已启动", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this, "无障碍权限未授予，无法启动 GUI Agent", Toast.LENGTH_LONG).show();
            requestAccessibilityPermission();
        }
    }

    private void parseSmsAndCreateCalendarEvent(String smsBody) {
        if (TextUtils.isEmpty(smsBody)) {
            return;
        }
        Log.d(TAG, "Attempting to parse SMS for calendar event: " + smsBody);

        Long eventBeginTimeMillis = null;
        Pattern datePattern = Pattern.compile("(\\d{1,2})月(\\d{1,2})号");
        Matcher dateMatcher = datePattern.matcher(smsBody);

        Calendar calendar = Calendar.getInstance();
        int currentYear = calendar.get(Calendar.YEAR);
        int month = -1, day = -1;

        if (dateMatcher.find()) {
            try {
                month = Integer.parseInt(dateMatcher.group(1)); // Month (1-12)
                day = Integer.parseInt(dateMatcher.group(2));   // Day
                calendar.set(currentYear, month - 1, day); // Calendar month is 0-indexed
                Log.d(TAG, "Parsed Date: Year=" + currentYear + ", Month=" + month + ", Day=" + day);
            } catch (NumberFormatException e) {
                Log.e(TAG, "Error parsing month/day from SMS", e);
            }
        } else {
            Log.d(TAG, "Date pattern (X月Y号) not found in SMS.");
        }

        if (month != -1 && day != -1) {
            if (smsBody.contains("晚")) {
                calendar.set(Calendar.HOUR_OF_DAY, 19); // 7 PM
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                eventBeginTimeMillis = calendar.getTimeInMillis();
                Log.d(TAG, "Parsed Time: Evening (set to 19:00). Event Start Millis: " + eventBeginTimeMillis);
            } else {
                calendar.set(Calendar.HOUR_OF_DAY, 12);
                calendar.set(Calendar.MINUTE, 0);
                eventBeginTimeMillis = calendar.getTimeInMillis();
                Log.d(TAG, "Parsed Time: No specific time part like '晚' found, defaulted to 12:00. Event Start Millis: " + eventBeginTimeMillis);

            }
        }

        String location = null;
        Pattern addressPattern = Pattern.compile("地址：([^【]+)");
        Matcher addressMatcher = addressPattern.matcher(smsBody);
        if (addressMatcher.find()) {
            location = addressMatcher.group(1).trim().split("\n")[0];
            Log.d(TAG, "Parsed Location (from 地址：): " + location);
        } else {
            Pattern placePattern = Pattern.compile("《([^》]+)》([^\\s]+店)?");
            Matcher placeMatcher = placePattern.matcher(smsBody);
            if (placeMatcher.find()) {
                location = placeMatcher.group(0).trim();
                Log.d(TAG, "Parsed Location (from 《》店): " + location);
            } else {
                Log.d(TAG, "Location pattern not found.");
            }
        }
        if (location != null) {
            location = location.replace("\n", " ").replaceAll("\\s+", " ").trim();
        }

        String title = "预约活动"; // Default title
        String description = smsBody; // Default description is the full SMS

        Pattern guestPattern = Pattern.compile("预订贵宾：([^\\s]+)");
        Matcher guestMatcher = guestPattern.matcher(smsBody);
        String guestName = "";
        if (guestMatcher.find()) {
            guestName = guestMatcher.group(1).trim();
        }

        Pattern placeNamePattern = Pattern.compile("《([^》]+)》");
        Matcher placeNameMatcher = placeNamePattern.matcher(smsBody);
        String extractedPlaceName = "";
        if (placeNameMatcher.find()) {
            extractedPlaceName = placeNameMatcher.group(1).trim();
        }

        if (!TextUtils.isEmpty(extractedPlaceName)) {
            title = "在 " + extractedPlaceName + " 的预约";
            if (!TextUtils.isEmpty(guestName)) {
                title += " (" + guestName + ")";
            }
        } else if (!TextUtils.isEmpty(guestName)) {
            title = guestName + " 的预约";
        }
        Log.d(TAG, "Parsed Event Title: " + title);

        // Add VIP room to description if found
        Pattern roomPattern = Pattern.compile("Vip包房：([^\\s]+)");
        Matcher roomMatcher = roomPattern.matcher(smsBody);
        if (roomMatcher.find()) {
            String room = roomMatcher.group(1).trim();
            description = "包房：" + room + "\n\n" + smsBody;
            Log.d(TAG, "Parsed Room: " + room);
        }
        Log.d(TAG, "Parsed Event Description: " + description);

        if (eventBeginTimeMillis != null) {
            ContentValues event = new ContentValues();
            event.put(CalendarContract.Events.CALENDAR_ID, 1); // 默认日历
            event.put(CalendarContract.Events.TITLE, "聚餐");
            event.put(CalendarContract.Events.DESCRIPTION, "聚餐提醒");
            event.put(CalendarContract.Events.EVENT_LOCATION, location);
            event.put(CalendarContract.Events.DTSTART, eventBeginTimeMillis);
            event.put(CalendarContract.Events.DTEND, eventBeginTimeMillis + 100);
            event.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
            event.put(CalendarContract.Events.HAS_ALARM, 1); // 设置提醒

            ContentResolver cr = getContentResolver();
            Uri eventUri = cr.insert(CalendarContract.Events.CONTENT_URI, event);

            if (eventUri != null) {
                long eventID = Long.parseLong(eventUri.getLastPathSegment());
                ContentValues reminder = new ContentValues();
                reminder.put(CalendarContract.Reminders.EVENT_ID, eventID);
                reminder.put(CalendarContract.Reminders.MINUTES, 10);
                reminder.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT);
                cr.insert(CalendarContract.Reminders.CONTENT_URI, reminder);

                Toast.makeText(this, "聚餐提醒已添加到日历", Toast.LENGTH_SHORT).show();

                File dir = getDir("models", Context.MODE_PRIVATE);
                String path = dir.getAbsolutePath() + File.separator;
                File file = new File(path + "input2.txt");
                FileOutputStream fos = null;
                OutputStreamWriter osw = null;

                try {
                    File parentDir = file.getParentFile();
                    if (parentDir != null && !parentDir.exists()) {
                        if (parentDir.mkdirs()) {
                            Log.d(TAG, "Parent directories created: " + parentDir.getAbsolutePath());
                        } else {
                            Log.e(TAG, "Failed to create parent directories: " + parentDir.getAbsolutePath());
                        }
                    }

                    fos = new FileOutputStream(file);
                    osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
                    osw.write("");
                    osw.flush(); // 确保内容写入文件
                    Log.d(TAG, "File written successfully to: " + path);
                } catch (IOException e) {
                    Log.e(TAG, "Error writing to file: " + path, e);
                } finally {
                    try {
                        if (osw != null) {
                            osw.close();
                        }
                        if (fos != null) {
                            fos.close();
                        }
                    } catch (IOException e) {
                        Log.e(TAG, "Error closing streams", e);
                    }
                }
            }

        } else {
            Toast.makeText(this, "未能从短信中解析出有效日期，无法创建日历事件。", Toast.LENGTH_LONG).show();
            Log.w(TAG, "Could not parse a valid date/time from SMS. Calendar event not created.");
        }
    }

    private void startFileCheckingLoop() {
        if (loadingIndicator != null) {
            loadingIndicator.setVisibility(View.VISIBLE); // Show loading indicator
        }
        Toast.makeText(this, "正在尝试读取数据...", Toast.LENGTH_SHORT).show();

        fileCheckHandler.post(new Runnable() {
            @Override
            public void run() {
                executorService.execute(() -> {
                    File modelsDir = getDir(MODELS_DIR_NAME, Context.MODE_PRIVATE);
                    File dataFile = new File(modelsDir, JSON_FILE_NAME);

                    Log.d(TAG, "Attempting to read from: " + dataFile.getAbsolutePath()); // 打印确切路径以供调试

                    if (dataFile.exists()) {
                        Log.d(TAG, "data.json found. Attempting to parse.");
                        List<CardItem> cardItems = loadPoisFromJson(dataFile);
                        Log.e(TAG, "run: cardItems.size() : " + cardItems.size());
                        runOnUiThread(() -> {
                            if (loadingIndicator != null) {
                                loadingIndicator.setVisibility(View.GONE); // Hide loading indicator
                            }
                            if (!cardItems.isEmpty()) {
                                adapter.updateData(cardItems); // Update adapter with new data
                                Toast.makeText(CardActivity.this, "数据加载成功!", Toast.LENGTH_SHORT).show();
                            } else {
                                Toast.makeText(CardActivity.this, "成功读取文件，但未能解析出数据或数据为空。", Toast.LENGTH_LONG).show();
                            }
                        });
                    } else {
                        Log.d(TAG, "data.json not found. Retrying in " + FILE_CHECK_INTERVAL_MS + "ms.");
                        runOnUiThread(() -> Toast.makeText(CardActivity.this, "未找到数据文件，" + (FILE_CHECK_INTERVAL_MS / 1000) + "秒后重试...", Toast.LENGTH_SHORT).show());
                        fileCheckHandler.postDelayed(this, FILE_CHECK_INTERVAL_MS);
                    }
                });
            }
        });
    }

    private List<CardItem> loadPoisFromJson(File dataFile) {
        List<CardItem> cardItems = new ArrayList<>();
        StringBuilder jsonContent = new StringBuilder();

        try (FileInputStream fis = new FileInputStream(dataFile);
             InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);
             BufferedReader br = new BufferedReader(isr)) {

            String line;
            while ((line = br.readLine()) != null) {
                jsonContent.append(line);
            }
        } catch (IOException e) {
            Log.e(TAG, "Error reading " + JSON_FILE_NAME, e);
            runOnUiThread(() -> Toast.makeText(CardActivity.this, "读取文件失败: " + e.getMessage(), Toast.LENGTH_LONG).show());
            return cardItems; // 返回空列表
        }

        if (jsonContent.length() == 0) {
            Log.e(TAG, "File is empty: " + JSON_FILE_NAME);
            runOnUiThread(() -> Toast.makeText(CardActivity.this, "文件内容为空", Toast.LENGTH_LONG).show());
            return cardItems;
        }

        try {
            JSONObject rootObject = new JSONObject(jsonContent.toString());
            JSONArray poisArray = rootObject.getJSONArray("pois");
            int[] cardColors = {R.drawable.card_gradient_1, R.drawable.card_gradient_2, R.drawable.card_gradient_3, R.drawable.card_gradient_4, R.drawable.card_gradient_5};
            int limit = Math.min(poisArray.length(), 5);

            for (int i = 0; i < limit; i++) {
                JSONObject poi = poisArray.getJSONObject(i);
                String name = poi.optString("name", "N/A");
                String address = poi.optString("address", "N/A");
                String phone = poi.optString("phone", "N/A");
                String photoUrl = poi.isNull("photo") ? "" : poi.optString("photo", "");
                int colorRes = cardColors[i % cardColors.length];
                cardItems.add(new CardItem(name, address, phone, photoUrl, colorRes));
            }
        } catch (JSONException e) {
            Log.e(TAG, "Error parsing JSON from " + JSON_FILE_NAME, e);
            runOnUiThread(() -> Toast.makeText(CardActivity.this, "解析JSON失败: " + e.getMessage(), Toast.LENGTH_LONG).show());
        }
        this.cardItems = cardItems; // 关键步骤
        return cardItems;
    }

    static class CardSpacingItemDecoration extends RecyclerView.ItemDecoration {
        private static final int SPACING = 1; // dp

        @Override
        public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,
                                   @NonNull RecyclerView parent,
                                   @NonNull RecyclerView.State state) {
            int position = parent.getChildAdapterPosition(view);
            if (position == 0) {
                outRect.top = dpToPx(SPACING);
            }
            outRect.bottom = dpToPx(SPACING);
            outRect.left = dpToPx(SPACING);
            outRect.right = dpToPx(SPACING);
        }

        private int dpToPx(int dp) {
            return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (telephonyManager != null && phoneStateListener != null &&
                ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
            telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
            Log.d(TAG, "PhoneStateListener re-registered in onResume.");
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (fileCheckHandler != null) {
            fileCheckHandler.removeCallbacksAndMessages(null);
        }
        if (telephonyManager != null && phoneStateListener != null) {
            telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (executorService != null && !executorService.isShutdown()) {
            executorService.shutdown();
        }
        if (fileCheckHandler != null) {
            fileCheckHandler.removeCallbacksAndMessages(null);
        }
        if (telephonyManager != null && phoneStateListener != null) {
            telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
            phoneStateListener = null; // Help garbage collection
        }
        telephonyManager = null;
    }

    private void checkAndRequestPermissions() {
        List<String> permissionsToRequest = new ArrayList<>();
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            permissionsToRequest.add(Manifest.permission.READ_EXTERNAL_STORAGE);
        }

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            permissionsToRequest.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED) {
            permissionsToRequest.add(Manifest.permission.INTERNET);
        }

        if (!permissionsToRequest.isEmpty()) {
            ActivityCompat.requestPermissions(this, permissionsToRequest.toArray(new String[0]), PERMISSION_REQUEST_CODE);
        }
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == PERMISSION_REQUEST_CODE_CALL_SMS_STATE_CALENDAR) {
            boolean allPermissionsGranted = true;
            for (int i = 0; i < permissions.length; i++) {
                if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
                    allPermissionsGranted = false;
                    Log.e(TAG, "Permission denied: " + permissions[i]);
                    if (permissions[i].equals(Manifest.permission.READ_CALENDAR)) {
                        Toast.makeText(this, "Read Calendar permission is required to show calendar events.", Toast.LENGTH_LONG).show();
                    }
                }
            }

            if (allPermissionsGranted) {
                Log.d(TAG, "All requested permissions granted.");
            } else {
                Log.e(TAG, "Not all requested permissions were granted.");
                Toast.makeText(this, "Some permissions were denied. Certain features might not work.", Toast.LENGTH_LONG).show();
                enableGuiAgentButton(false);
            }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == ACCESSIBILITY_REQUEST_CODE) {
            if (isAccessibilityServiceEnabled(this, GUIAgentService.class)) {
                startGuiAgentService();
            } else {
                Toast.makeText(this, "无障碍权限未授予，无法启动 GUI Agent", Toast.LENGTH_LONG).show();
            }
        }
    }
}
